/************************************************
  class Parser.
  a Parser class that takes a file and parses it into tokens
  Rules: ignore blanks, tabs and whatever


************************************************/

#include "Parser.h"

using namespace std;

Parser::Parser(){
	lineNum =0;
	inputLineSet=false;
	bool fileOpened=false;
	input=NULL;
	}

Parser::~Parser(){
		if (fileOpened){
			file.close();
		}
		while(tokens.size()>0){
			delete(tokens.front());
			tokens.pop();
		}
	}

void Parser::getToken(Token& tok){

	if ((!fileOpened) || (!inputLineSet)){
		tok.setBadToken();
		return;
	}
	while (tokens.size() < 1 && (file.good())){// if need to read more tokens
		readTokens(); //tokens read & its an empty line - read more
	}
	if ((tokens.size() < 1) && (!file.good())){
		//EOF - send eof token
		tok.setEofToken();
	} else {
		//we have tokens
		tok = *tokens.front();//copy fields
		delete(tokens.front()); //del the token
		tokens.pop(); //remove

	}
}

	// virtual to allow opening files in formats other then ascii.
bool Parser::setFile(const std::string fileName){
	file.open(fileName);
	if (file && file.good()){
		fileOpened = true;
	} else {
		fileOpened = false;
		throw string("IO Error: cannot open file");
	}
	return fileOpened;
}

void Parser::setInputLine(const InputLine * const in){
	if (in==NULL){
		inputLineSet = false;
	} else {
		inputLineSet = true;
	}
	input = in;
}

	//getline would work only if pareser is ready.
bool Parser::isParserReady() const{
	return (inputLineSet && fileOpened);
}

void Parser::readTokens(){
	string line;

	if (file.eof() || file.fail() || file.bad()){
		if (file.fail() || file.bad()){
			throw string("IO Error: cannot read from file");
		}
		return;
	}
	getline(file,line);
	if (file.fail() || file.bad()){
			throw string("IO Error: cannot read from file");
	}
	lineNum++;
	input->getLine(this->tokens,line,lineNum);

}

